/*
 * Copyright (c) 2017 - 2019, AEye, Inc.
 * All rights reserved.
 */

//////////////////////////////////////////////////
/// CircularBuffer.hpp
///   a simple circular buffer template using a
///  std::vector as basic data structure.
#ifndef CIRCULARBUFFER_HPP
#define CIRCULARBUFFER_HPP

#include <vector>
#include <exception>

template <class T>
class CircularBuffer {
public:
  CircularBuffer() : _buffer(0), _ptr(0) {}

  explicit CircularBuffer(uint size) : _buffer(size), _ptr(0) {}

  ///////////////////////////////////////////////////////
  /// \brief operator []
  /// \param i : burden on caller to avoid out of range i
  /// \return
  ///
  T& operator [](size_t i) { return _buffer[i]; }

  T& head() { return _buffer[_ptr]; }

  size_t size() { return _buffer.size(); }

  void resize(size_t size) { _buffer.resize(size); }

  size_t incrementPtr() {
    _ptr = (_ptr + 1) % _buffer.size();
    return _ptr;
  }

  void addNext(T& val) {
    _buffer[_ptr] = val;
    incrementPtr();
  }

protected:
  std::vector<T> _buffer;
  size_t         _ptr;
};

#endif // CIRCULARBUFFER_HPP
